package cnu.cse.crawler.manager;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ConnectionManager 
{
	///////////////////////////////////////////// Member /////////////////////////////////////////////
	//
	//
	
	private static ConnectionManager instance = new ConnectionManager();
	
	private List<String> cookies;
	private HttpURLConnection httpCon;
	private HttpsURLConnection httpsCon;
	
	
	
	
	
	
	////////////////////////////////// Constructor and Initializer ///////////////////////////////////
	//
	//
	
	private ConnectionManager()
	{
		
	}
	
	public static ConnectionManager getInstance()
	{
		return instance;
	}
	
	
	
	
	
	
	//////////////////////////////////////// Private Methods ////////////////////////////////////////
	//
	//
	
	/*
	private List<String> getCookies()
	{
		return cookies;
	}
	*/
		 
	private void setCookies(List<String> cookies)
	{
		this.cookies = cookies;
	}
	
	
	
	
	
	
	//////////////////////////////////////// Public Methods ////////////////////////////////////////
	//
	//
	
	public String httpGetRequest(String url) throws Exception 
	{
		URL obj = new URL(url);
		httpCon = (HttpURLConnection) obj.openConnection();		
		 
		// act such as browser
		httpCon.setUseCaches(false);
		httpCon.setRequestMethod("GET");
		httpCon.setRequestProperty("Host", "computer.cnu.ac.kr");
		httpCon.setRequestProperty("Connection", "keep-alive");
		httpCon.setRequestProperty("Cache-Control", "max-age=0");
		httpCon.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36");
		httpCon.setRequestProperty("Accept-Encoding", "gzip,deflate,sdch");
		httpCon.setRequestProperty("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4");

		if (cookies != null) 
		{
			for (String cookie : this.cookies) 
			{
				httpCon.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
			}
		}

		int responseCode = httpCon.getResponseCode();
		if (responseCode == 200)
		{
			BufferedReader in = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();
		 
			while ((inputLine = in.readLine()) != null) 
			{
				response.append(inputLine);
			}
			in.close();
		 
			// get the response cookies
			setCookies(httpCon.getHeaderFields().get("Set-Cookie"));
			
			return response.toString();
		}
		else
		{
			return null;
		}
		
	}
		
	public String httpsGetRequest(String url) throws Exception 
	{ 
		URL obj = new URL(url);
		httpsCon = (HttpsURLConnection) obj.openConnection();		
		 
		// act like a browser
		httpsCon.setUseCaches(false);
		httpsCon.setRequestMethod("GET");
		httpsCon.setRequestProperty("Host", "computer.cnu.ac.kr");
		httpsCon.setRequestProperty("Connection", "keep-alive");
		httpsCon.setRequestProperty("Cache-Control", "max-age=0");
		httpsCon.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		httpsCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36");
		httpsCon.setRequestProperty("Accept-Encoding", "gzip,deflate,sdch");
		httpsCon.setRequestProperty("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4");

		if (cookies != null) 
		{
			for (String cookie : this.cookies) 
			{
				httpsCon.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
			}
		}

		int responseCode = httpsCon.getResponseCode();
		if (responseCode == 200)
		{
			BufferedReader in = new BufferedReader(new InputStreamReader(httpsCon.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();
			 
			while ((inputLine = in.readLine()) != null) 
			{
				response.append(inputLine);
			}
			in.close();
			 
			// get the response cookies
			setCookies(httpsCon.getHeaderFields().get("Set-Cookie"));
			
			return response.toString();
		}
		else
		{
			return null;
		}
	}
	
	public String getLoginFormParameterList(String html, String id, String pwd) throws UnsupportedEncodingException 
	{
		Document doc = Jsoup.parse(html);
	  
		// get the 'https://computer.cnu.ac.kr/_login' login form
		Element loginform = doc.getElementsByTag("form").first();
		Elements inputElements = loginform.getElementsByTag("input");
		List<String> paramList = new ArrayList<String>();
		
		paramList.add("ssl=" + URLEncoder.encode("on", "UTF-8"));
		
		for (Element inputElement : inputElements) 
		{
			String key = inputElement.attr("name");
			String value = inputElement.attr("value");
	 
			if (key.equals("UID"))
			{
				value = id;
			}
			else if (key.equals("PASSWD"))
			{
				value = pwd;
			}
			
			paramList.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
		}
		
		paramList.add("loginnow.x=" + URLEncoder.encode("0", "UTF-8"));
		paramList.add("loginnow.y=" + URLEncoder.encode("0", "UTF-8"));
	 
		// build a parameters list
		StringBuilder result = new StringBuilder();
		
		for (String param : paramList) 
		{
			if (result.length() == 0) 
			{
				result.append(param);
			} 
			else 
			{
				result.append("&" + param);
			}
		}
		
		return result.toString();
	}
	
	public String httpsPostRequestForLogin(String url, String postParams) throws Exception
	{
		URL obj = new URL(url);
		httpsCon = (HttpsURLConnection) obj.openConnection();
		
		// act such as a browser
		httpsCon.setUseCaches(false);		
		httpsCon.setRequestMethod("POST");
		httpsCon.setRequestProperty("Host", "computer.cnu.ac.kr");
		httpsCon.setRequestProperty("Connection", "keep-alive");
		httpsCon.setRequestProperty("Content-Length", Integer.toString(postParams.length()));
		httpsCon.setRequestProperty("Cache-Control", "max-age=0");
		httpsCon.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		httpsCon.setRequestProperty("Origin", "http://computer.cnu.ac.kr");
		httpsCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36");
		httpsCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");		
		httpsCon.setRequestProperty("Referer", "http://computer.cnu.ac.kr/main_cache.html");
		httpsCon.setRequestProperty("Accept-Encoding", "gzip,deflate,sdch");
		httpsCon.setRequestProperty("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4");
		
		/*
		for (String cookie : this.cookies)
		{
			httpsCon.setRequestProperty("Cookie", cookie.split(";", 1)[0]);
		}
		*/
				
		httpsCon.setDoOutput(true);
		httpsCon.setDoInput(true);
		
		// send a post request
		DataOutputStream wr = new DataOutputStream(httpsCon.getOutputStream());
		wr.writeBytes(postParams);
		wr.flush();
		wr.close();
	 
		int responseCode = httpsCon.getResponseCode();
		if (responseCode == 200)
		{
			BufferedReader in = new BufferedReader(new InputStreamReader(httpsCon.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();
		 
			while ((inputLine = in.readLine()) != null) 
			{
				response.append(inputLine);
			}
			in.close();
			
			return response.toString();
		}
		else
		{
			return null;
		}
	}
	
	
	
}
